#include "stdio.h"
#include "stdlib.h"
#include "assert.h"
#include "err.h"
#include "bool.h"
#include "arista.h"
#include "colap.h"
#include "union.h"
#include "pila.h"
#include "cintrar.h"
#include "cintwar.h"

int main(void){

	colap cp;
	union_find ccv;
	cintrar cr;
	cintwar cw;
	stack s1,s2;
	tarista e;
	tufset cv1, cv2;
	int vertices,aristas;
	vuvuzela vuvu;

	cr = cra_create();
	cw = cwa_create();
	if (cr == NULL || cw == NULL){
		if (cr != NULL) cr = cra_destroy(cr);
		if (cw != NULL) cw = cwa_destroy(cw);
		errx(EXIT_FAILURE,"No hay memoria disponible");
	}

	cra_arr(cr);
	vertices = cra_cantvert(cr);
	aristas = cra_cantaris(cr);

	cp = colap_create(aristas);
	ccv = uf_create(vertices);
	s1 = stack_create(aristas);
	s2 = stack_create(aristas);
	if (cp == NULL || ccv == NULL || s1 == NULL || s2 == NULL){
		if (cr != NULL) cr = cra_destroy(cr);
		if (cw != NULL) cw = cwa_destroy(cw);
		if (cp != NULL) cp = colap_destroy(cp);
		if (ccv != NULL) ccv = uf_destroy(ccv);
		if (s1 != NULL) s1 = stack_destroy(s1);
		if (s2 != NULL) s2 = stack_destroy(s2);
		errx(EXIT_FAILURE,"No hay memoria disponible");
	}

	while (!cra_fin(cr)){
		e = cra_elec(cr);
		colap_encolar(cp, e);
		uf_add_singulete(ccv,vertice1(e));
		uf_add_singulete(ccv,vertice2(e));
		cra_av(cr);
	}

	while (!uf_oneset(ccv) && !colap_vacia(cp)){
		e = colap_primero(cp);
		colap_pop(cp);
		cv1 = uf_find(ccv,vertice1(e));
		cv2 = uf_find(ccv,vertice2(e));
		if (cv1 != cv2){
			uf_union(ccv,cv1,cv2);
			stack_push(s1,e);
		}
		else stack_push(s2,e);
	}

	if (uf_cantset(ccv) > 1){
		printf("La cantidad de componentes conexas es: %d\n",uf_cantset(ccv));
	}

	vuvu = vuvu_create(vertices);
	cwa_arr(cw);
	while (!stack_vacia(s1)){
		e = stack_top(s1);
		stack_pop(s1);
		cwa_insarbol(cw,e,vuvu);
		e = arista_destroy(e);
	}

	while (!stack_vacia(s2)){
		e = stack_top(s2);
		stack_pop(s2);
		cwa_insrest(cw,e,vuvu);
		e = arista_destroy(e);
	}

	while (!colap_vacia(cp)){
		e = colap_saca(cp);
		cwa_insrest(cw,e,vuvu);
		e = arista_destroy(e);
	}

	vuvu = vuvu_destroy(vuvu);
	s1 = stack_destroy(s1);
	s2 = stack_destroy(s2);
	cw = cwa_destroy(cw);
	cr = cra_destroy(cr);
	ccv = uf_destroy(ccv);
	cp = colap_destroy(cp);

	return 0;
}

